// cLDAPResolver.cpp: implementation of the cLDAPResolver class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "qpmig.h"
#include "cLDAPResolver.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

cLDAPResolver::cLDAPResolver(LPCSTR pPath)
{
	m_strLDAPPath=pPath;
	m_bInit=FALSE;
	pSes = NULL;
	pControl =NULL;

}

cLDAPResolver::~cLDAPResolver()
{
if(pSes)
	ldap_unbind(pSes);


}


CString cLDAPResolver::ResolveUser(LPCSTR strUserEmail)
{
	if(!m_bInit)
		{
			Init();
			m_bInit=TRUE;

		}
	CString cQuery,cDomain,cUser;
	int Pos;
							
	ULONG lRtn = LDAP_SUCCESS;;
	LDAPMessage* pMes = NULL;
	LDAPMessage* pEntry = NULL;
	PLDAPControl    *pvlvresponse = NULL;
	BOOL Cont=TRUE;
	CString s;
	CString cInfo;
	

	LDAPSearch *pSearch =NULL;
	ULONG MessageNr=0;
	struct berval *cookie;
	ULONG ulCount;
	LDAP_TIMEVAL tv;
	tv.tv_sec=1200;
	int i=0;
	tv.tv_usec=0;
	CString cPath=m_strLDAPPath;
	int pos=cPath.Find("://");
	if(pos>0)
		cPath=cPath.Mid(pos+3);
	PLDAPControl    ctrlArr[2];
	CString cResolved;

	// Attributes to retrieve
	 TCHAR   *szAttribs[]={

				{"distinguishedname"},
				{"samAccountName"},
        NULL
    };
		
	BOOL Resolved=FALSE;
	Cont=TRUE;
	cQuery.Format("mail=%s",strUserEmail);
	while(Cont)
		{
			ctrlArr[0]=pControl;
			ctrlArr[1]=NULL;
 			


			lRtn = ldap_search_ext(pSes, cPath.GetBuffer(cPath.GetLength()), LDAP_SCOPE_SUBTREE , 
				cQuery.GetBuffer(255), szAttribs,  0, 
				ctrlArr,NULL,100000,10,&MessageNr);
			cPath.ReleaseBuffer();
			cQuery.ReleaseBuffer();
			if(lRtn != LDAP_SUCCESS)
				 break;
			lRtn = ldap_result(pSes,MessageNr,LDAP_MSG_ALL,&tv,&pMes);
			if(lRtn == -1)
				 break;
			if(ldap_count_entries(pSes,pMes)<10)
				Cont=FALSE;
			pEntry = ldap_first_entry(pSes, pMes); 
			if(pEntry == NULL)
				{
					lRtn = LdapGetLastError();
					if(lRtn == LDAP_SUCCESS)
						lRtn = LDAP_OTHER;
				 Cont=FALSE;
				}
			else
				{
					
					PCHAR* pV=ldap_get_values(pSes,pEntry,"distinguishedname"); 
					if(pV)
						{
							cDomain=*pV;
							Pos=cDomain.Find("DC=");
							if(Pos>0)
								cDomain=cDomain.Mid(Pos+3);
							Pos=cDomain.Find(",");
							if(Pos>0)
								cDomain=cDomain.Left(Pos);
							ldap_value_free(pV);
						}
					pV=ldap_get_values(pSes,pEntry,"samAccountName"); 
					if(pV)
						{
							s=*pV;
							cResolved.Format("%s\\%s",cDomain,s);
							ldap_value_free(pV);
							Resolved=TRUE;
						}


				}

			lRtn =  ldap_parse_result(pSes,pMes,NULL,NULL,NULL,NULL,&pvlvresponse ,0);
			if( lRtn != LDAP_SUCCESS )
				Cont=FALSE;
			lRtn =  ldap_parse_page_control (pSes,pvlvresponse ,&ulCount,&cookie);
			if(lRtn != LDAP_SUCCESS)
				Cont=FALSE;
			ldap_control_free(pControl);
			lRtn = ldap_create_page_control(pSes,10,cookie,0,&pControl);
			if(lRtn != LDAP_SUCCESS)
				Cont=FALSE;

		 if(pMes != NULL)
			 {
					ldap_msgfree(pMes);
					pMes=NULL;
			 }
      
   }
	return cResolved;

}

void cLDAPResolver::Init()
{
	ULONG version = LDAP_VERSION3;
	ULONG lRtn = LDAP_SUCCESS;;
	// create a new LDAP session
	pSes = ldap_init(NULL,LDAP_PORT);

	if(pSes == NULL)
	 {
			lRtn = LdapGetLastError();
			if(lRtn == LDAP_SUCCESS)
				lRtn = LDAP_OTHER;
			}
  if(lRtn != LDAP_SUCCESS)
		{
			AfxMessageBox("Ldap_ini failed");
			return ;
		}
	CString cPath=m_strLDAPPath;
	int pos=cPath.Find("://");
	if(pos>0)
		cPath=cPath.Mid(pos+3);


	lRtn  = ldap_bind_s( pSes , NULL, NULL, LDAP_AUTH_NEGOTIATE );
  if(lRtn != LDAP_SUCCESS)
		{
			AfxMessageBox("Unable to connect the Active Directory");
			return;
		}
	int i=0;
	if(i)
		lRtn = ldap_set_option(pSes,LDAP_OPT_VERSION,(void*)&version);
	// Make sure we use Version 3 support
	
  if(lRtn != LDAP_SUCCESS)
		{
			AfxMessageBox("No LDAP v3 support");
			return;
		}

// Make sure we dont deref aliases
	ULONG option = LDAP_DEREF_NEVER;

	lRtn = ldap_set_option(pSes,LDAP_OPT_DEREF,(void*)&option );
  if(lRtn != LDAP_SUCCESS)
		{
			AfxMessageBox("No LDAP v3 support");
			return;
		}
// Make sure we dont follow referrals
	option = (ULONG)LDAP_OPT_OFF;

	lRtn = ldap_set_option(pSes,LDAP_OPT_REFERRALS ,(void*)&option );
  if(lRtn != LDAP_SUCCESS)
		{
			AfxMessageBox("No LDAP v3 support");
			return;
		}

	lRtn = ldap_create_page_control(pSes,5,NULL,0,&pControl);
  if(lRtn != LDAP_SUCCESS)
		{
			AfxMessageBox("Could not create paging control");
			return;
		}

}
